
#include "util.h"
#include "los_tick.h"
#include <string.h>

uint32_t TickerStart(void) {
    return LOS_TickCountGet();
}

/**
 * @brief 将二进制数转换为小端序BCD码
 * @param val  输入的二进制数值
 * @param pData 输出缓冲区（需预先分配足够空间）
 * @param len  期望的BCD字节数（如len=4，可表示最大99999999）
 * @note  若转换结果超出len指定的字节数，高位会被截断
 */
void BinToBcd(u32 val, u8* pData, u8 len)
{
    if (!pData || len == 0) return;

    // 清零输出缓冲区
    for (u8 i = 0; i < len; i++) {
        pData[i] = 0;
    }

    // 逐位转换（小端序：低位字节在前）
    u8 pos = 0;
    while (val > 0 && pos < len) {
        u8 digit = val % 10;       // 取最低位数字
        val /= 10;                // 移除已处理位

        // 合并到当前字节（小端序：新数字放在字节低4位）
        pData[pos] |= (digit << 0); // 写入当前字节的低4位

        // 处理下一个十进制位
        digit = val % 10;
        val /= 10;
        pData[pos] |= (digit << 4); // 写入当前字节的高4位

        pos++; // 处理下一个字节
    }
}

/**
 * @brief 将 BCD 码数组转换为二进制整数（支持大小端选择）
 * @param pData       指向 BCD 码数组的指针（每个字节存储 2 位十进制数）
 * @param len         BCD 码数组的长度（字节数）
 * @param is_big_endian 是否按大端模式解析（true: 大端, false: 小端）
 * @return 转换后的 32 位无符号整数（非法 BCD 码返回 0）
 */
u32 BcdToBin(u8 *pData, u8 len, bool is_big_endian) {
    u32 result = 0;

    // 遍历 BCD 字节（根据大小端调整顺序）
    for (u8 i = 0; i < len; i++) {
        u8 bcd_byte;
        if (is_big_endian) {
            // 大端模式：从高位到低位解析
            bcd_byte = pData[i];
        } else {
            // 小端模式：反转字节顺序（如 [0x34, 0x12] -> 按 0x12, 0x34 解析）
            bcd_byte = pData[len - 1 - i];
        }

        // 检查是否为有效 BCD 码（每个 nibble 必须 ≤ 9）
        if ((bcd_byte & 0x0F) > 9 || (bcd_byte >> 4) > 9) {
            return 0; // 非法 BCD 码
        }

        // 高 4 位（十位）和低 4 位（个位）分别转换
        u8 high_nibble = (bcd_byte >> 4) * 10;
        u8 low_nibble = bcd_byte & 0x0F;
        u8 decimal_value = high_nibble + low_nibble;

        // 累加到结果（考虑位数权重）
        result = result * 100 + decimal_value;
    }

    return result;
}
bool TickerOut(uint32_t start, uint32_t duration_ticks) {
    uint32_t now = LOS_TickCountGet();
    // 处理tick计数器溢出
    if(now >= start) {
        if((now - start) >= duration_ticks)
        return true;
        else 
        return false;
    } else {
        if((UINT32_MAX - start + now) >= duration_ticks)
        return true;
        else 
        return false;
    }
}

bool TickerOutCheck(uint32_t time, uint32_t duration_ticks) {
    uint32_t now = LOS_TickCountGet();
    // 处理tick计数器溢出
    if( now>=time ) {
        if((now-time) >= duration_ticks)
        {
            return true;
        }
        else 
        {
            return false;
        }
        
    } 
}


uint32_t MS2TICKS(uint32_t ms) {
    // 假设系统tick频率为100Hz (每tick=10ms)
    return ms / 10; 
    // 实际值需根据LOSCFG_BASE_CORE_TICK_PER_SECOND调整
}


// 确保返回非零值的计时器起点
uint32_t TickerStart_RtnNonZero(void) {
    uint32_t tick = LOS_TickCountGet();
    
    // 如果当前tick为0，返回1（最小非零值）
//    return (tick == 0) ? 1 : tick;
    
    /* 更健壮的方案（处理tick即将溢出）*/
     return (tick == 0 || tick == UINT32_MAX) ? 1 : tick;
}


u16 LoadInt16_BigE(u8 *pData) {
    // 大端序转本地字节序
    return (u16)((pData[0] << 8) | pData[1]);
}

u32 LoadInt32_BigE(u8 *pData) {
    // 大端序转本地字节序
    return (u32)((pData[0] << 24) | (pData[1] << 16) | (pData[2] << 8) | pData[3]);
}

u16 LoadInt16(u8 *pData) {
    // 直接读取小端序数据
    return *(u16 *)pData; 
}

u32 LoadInt32(u8 *pData) {
    // 直接读取小端序数据（无需转换）
    return *(u32 *)pData; 
}

u8 CalChkSum(u8* array, u16 len) {
    u8 sum = 0;
    for (size_t i = 0; i < len; i++) { // 假设校验码是最后一个元素
        sum += array[i];
    }
    return (u8)sum;
}
